#ifndef _SE_COMPONENTS_
#define _SE_COMPONENTS_

#include "Core/GUID.h"

#include "Render/RenderContext.h"

#include "Resources/MeshInstance.h"

namespace SE
{
	//--------------------------------------
	/* Tag component */
	struct TagComponent final
	{
		String tag = "Null";

		TagComponent() = default;
		TagComponent(const String& _tag);
		~TagComponent() = default;
	};
	//--------------------------------------

	//--------------------------------------
	/* GUID component */
	struct GUIDComponent final
	{
		GUID guid;

		GUIDComponent() = default;
		GUIDComponent(const GUID& _guid);
		~GUIDComponent() = default;
	};
	//--------------------------------------

	//--------------------------------------
	/* Transform component */
	struct TransformComponent final
	{
		Vector3f position	= Vector3f(0.0f);
		Vector3f rotation	= Vector3f(0.0f);  // Euler angles.
		Vector3f scale		= Vector3f(1.0f);

		TransformComponent() = default;
		TransformComponent(
			const Vector3f& _position,
			const Vector3f& _rotation,
			const Vector3f& _scale);
		~TransformComponent() = default;

		Matrix4f getTransform() const;

		String record() const;
	};
	//--------------------------------------

	//--------------------------------------
	/* Camera component */
	static constexpr Vector3f WorldUpDirection		= Vector3f(0.0f, 1.0f, 0.0f);
	static constexpr Vector3f WorldRightDirection	= Vector3f(1.0f, 0.0f, 0.0f);
	static constexpr Vector3f WorldForwardDirection = Vector3f(0.0f, 0.0f,-1.0f);

	enum class CameraType
	{
		Perspective = 0, Orthographic = 1
	};

	struct CameraComponent final
	{
		Boolean		actived = false;
		CameraType	type = CameraType::Perspective;

		// For orthographic camera.
		Float		orthographicSize = 10.0f;
		Float		orthographicNear = -0.1f;
		Float		orthographicFar = 1000.0f;

		// For perspective camera.
		Float		perspectiveFOV = 45.0f;
		Float		perspectiveNear = 0.1f;
		Float		perspectiveFar = 1000.0f;

		CameraComponent() = default;
		~CameraComponent() = default;

		Matrix4f getProjection() const;
	};
	//--------------------------------------

	//--------------------------------------
	/* Mesh renderer component */
	struct MeshRendererComponent final
	{
		Ref<MeshInstance> meshInstance = CreateRef<BezierSurface>();

		MeshRendererComponent() = default;
		~MeshRendererComponent() = default;
	};
	//--------------------------------------

	//--------------------------------------
	/* Scriptable component */
	class NativeScript;
	struct ScriptableComponent final
	{
		Ref<NativeScript> script;

		ScriptableComponent() = default;
		~ScriptableComponent() = default;

		template<typename _Ty>
		void bind()
		{
			script = CreateRef<_Ty>();
		}
	};
	//--------------------------------------
} // !namespace SE

#endif // !_SE_COMPONENTS_